home *** CD-ROM | disk | FTP | other *** search
/ Sky at Night 2006 September / SAN CD 9-2006 CD-ROM 16.iso / pc / Software / Network Telescope Control / NTC-Setup.Exe / Source / ntc_client_control.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2006-03-24  |  33.2 KB  |  1,529 lines

  1. unit ntc_client_control;
  2. {
  3.     Copyright (C) 2004 - 2006 Andrew Sprott
  4.  
  5.     http://astronomy.crysania.co.uk
  6.     astro@trefach.co.uk
  7.  
  8.     This program is free software; you can redistribute it and/or
  9.     modify it under the terms of the GNU General Public License
  10.     as published by the Free Software Foundation; either version 2
  11.     of the License, or (at your option) any later version.
  12.  
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16.     GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to the Free Software
  20.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. }
  22.  
  23. interface
  24.  
  25. uses
  26.     Windows,
  27.     Messages,
  28.     SysUtils,
  29.     Variants,
  30.     Classes,
  31.     Graphics,
  32.     Controls,
  33.     Forms,
  34.     Dialogs,
  35.     StdCtrls,
  36.     ExtCtrls,
  37.     Buttons,
  38.     inifiles,
  39.     ComCtrls,
  40.  
  41.     ntc_client_form;
  42.  
  43. const
  44.     { scope types }
  45.     max_speeds=25;
  46.     window_track_max=50;
  47.     window_track_step=2;
  48.     window_method=0;
  49.     degree_method=1;
  50.     window_percent_default=80;
  51.     move_degrees_default=0;
  52.     move_minutes_default=0;
  53.     move_seconds_default=1;
  54.     { basics }
  55.     minutes_in_degree=60;
  56.     seconds_in_minute=60;
  57.     max_degrees=360;
  58.     max_degrees_dec=90;
  59.     max_hours=24;
  60.     cr=#13;
  61.  
  62. type
  63.     buttons_type_set=(
  64.         button_north,
  65.         button_south,
  66.         button_east,
  67.         button_west);
  68.     buttons_type=set of buttons_type_set;
  69.  
  70. const
  71.     buttons_all:buttons_type=[
  72.         button_north,
  73.         button_south,
  74.         button_east,
  75.         button_west];
  76.  
  77. type
  78.     Tscope_control = class(tform)
  79.         control_panel: TPanel;
  80.         slew_group: TGroupBox;
  81.         north_button: TSpeedButton;
  82.         east_button: TSpeedButton;
  83.         west_button: TSpeedButton;
  84.         south_button: TSpeedButton;
  85.     stop_button: TSpeedButton;
  86.         north_label: TLabel;
  87.         west_label: TLabel;
  88.         south_label: TLabel;
  89.         east_label: TLabel;
  90.         connect_group: TGroupBox;
  91.         connect_button: TSpeedButton;
  92.         disconnect_button: TSpeedButton;
  93.         led_display: TEdit;
  94.         goto_group: TGroupBox;
  95.         ra_hours_edit: TEdit;
  96.         ra_minutes_edit: TEdit;
  97.         ra_seconds_edit: TEdit;
  98.         dec_degrees_edit: TEdit;
  99.         dec_minutes_edit: TEdit;
  100.         dec_seconds_edit: TEdit;
  101.         ra_label: TLabel;
  102.         dec_label: TLabel;
  103.         hours_label: TLabel;
  104.         ra_minutes_label: TLabel;
  105.         ra_seconds_label: TLabel;
  106.         dec_minutes_label: TLabel;
  107.         dec_seconds_label: TLabel;
  108.         degrees_label: TLabel;
  109.         goto_button: TBitBtn;
  110.         locked_check: TCheckBox;
  111.         ra_hours_up_down: TUpDown;
  112.     dec_degrees_up_down: TUpDown;
  113.         ra_minutes_up_down: TUpDown;
  114.         dec_minutes_up_down: TUpDown;
  115.         ra_seconds_up_down: TUpDown;
  116.         dec_seconds_up_down: TUpDown;
  117.         refresh_button: TBitBtn;
  118.         move_units_group: TGroupBox;
  119.         move_degrees_up_down: TUpDown;
  120.         move_minutes_up_down: TUpDown;
  121.         move_degrees_edit: TEdit;
  122.         move_minutes_edit: TEdit;
  123.         move_seconds_edit: TEdit;
  124.         move_seconds_up_down: TUpDown;
  125.         move_seconds_label: TLabel;
  126.         move_minutes_label: TLabel;
  127.         move_degrees_label: TLabel;
  128.         window_move_button: TSpeedButton;
  129.         degree_move_button: TSpeedButton;
  130.         move_window_group: TGroupBox;
  131.         degrees_edit: TEdit;
  132.         window_track: TTrackBar;
  133.         window_label: TLabel;
  134.  
  135.         { form functions }
  136.         procedure formcreate(
  137.             Sender:TObject);
  138.  
  139.         procedure form_close_query(
  140.                     Sender: TObject;
  141.             var CanClose: Boolean);
  142.  
  143.         { scope linkage }
  144.         procedure flip_buttons(
  145.             toggle:boolean);
  146.  
  147.         procedure change_panel(
  148.             toggle:boolean);
  149.  
  150.         procedure connect_to_scope;
  151.  
  152.         procedure disconnect_from_scope;
  153.  
  154.         { directional controls }
  155.         procedure stop_failed;
  156.  
  157.         procedure move_down;
  158.         procedure move_up;
  159.         procedure move_left;
  160.         procedure move_right;
  161.  
  162.         procedure move_distance(
  163.             d:string);
  164.  
  165.         procedure north_button_down(
  166.             Sender:TObject);
  167.  
  168.         procedure south_button_down(
  169.             Sender:TObject);
  170.  
  171.         procedure east_button_down(
  172.             Sender:TObject);
  173.  
  174.         procedure west_button_down(
  175.             Sender:TObject);
  176.  
  177.         procedure stop_button_down(
  178.             Sender:TObject);
  179.  
  180.         procedure stop_scope;
  181.  
  182.         { goto }
  183.         procedure go_to;
  184.  
  185.         { speed controls }
  186.         procedure update_speed_group(
  187.             speed_box:tpanel;
  188.             first_speed_button:tspeedbutton;
  189.             start_speed,
  190.             speed_count:integer;
  191.             event:TNotifyEvent;
  192.             can_do:boolean);
  193.  
  194.         function set_slew_speed(
  195.             speed_box:tpanel)
  196.             :integer;
  197.  
  198.         { logging }
  199.         procedure write_status_log(
  200.             e:string);
  201.  
  202.         { configuration }
  203.         procedure load_settings;
  204.  
  205.         procedure save_settings;
  206.  
  207.         { utilites }
  208.         procedure change_window_method;
  209.         procedure change_degree_method;
  210.  
  211.         procedure update_degrees;
  212.  
  213.         procedure update_edit_boxes;
  214.         procedure update_ra_edit_boxes;
  215.         procedure update_dec_edit_boxes;
  216.  
  217.         { events }
  218.         procedure FormShow(
  219.             Sender:TObject);
  220.  
  221.         procedure adjust;
  222.  
  223.         procedure check_activate(
  224.             Sender: TObject);
  225.  
  226.         procedure east_labelClick(
  227.             Sender: TObject);
  228.  
  229.         procedure west_labelClick(
  230.             Sender: TObject);
  231.  
  232.         procedure north_labelClick(
  233.             Sender: TObject);
  234.  
  235.         procedure south_labelClick(
  236.             Sender: TObject);
  237.  
  238.         procedure disconnect_from_scope_click(
  239.             Sender:TObject);
  240.  
  241.         procedure connect_to_scope_click(
  242.             sender:tobject);
  243.  
  244.         procedure goto_buttonClick(
  245.             Sender: TObject);
  246.  
  247.         procedure window_move_buttonClick(
  248.             Sender: TObject);
  249.  
  250.         procedure degree_move_buttonClick(
  251.             Sender: TObject);
  252.  
  253.         procedure window_trackChange(
  254.             Sender: TObject);
  255.  
  256.         procedure degrees_editKeyPress(
  257.                     Sender: TObject;
  258.             var Key: Char);
  259.  
  260.         procedure move_degrees_editKeyPress(
  261.                     Sender: TObject;
  262.             var Key: Char);
  263.  
  264.         procedure move_minutes_editKeyPress(
  265.                     Sender: TObject;
  266.             var Key: Char);
  267.  
  268.         procedure move_seconds_editKeyPress(
  269.                     Sender: TObject;
  270.             var Key: Char);
  271.  
  272.         procedure move_degrees_up_downChanging(
  273.                     Sender: TObject;
  274.             var AllowChange: Boolean);
  275.  
  276.         procedure move_minutes_up_downChanging(
  277.                     Sender: TObject;
  278.             var AllowChange: Boolean);
  279.  
  280.         procedure move_seconds_up_downChanging(
  281.                     Sender: TObject;
  282.             var AllowChange: Boolean);
  283.  
  284.         procedure move_degrees_editEnter(
  285.             Sender: TObject);
  286.  
  287.         procedure ra_hours_editKeyPress(
  288.                     Sender: TObject;
  289.             var Key: Char);
  290.  
  291.         procedure ra_minutes_editKeyPress(
  292.                     Sender: TObject;
  293.             var Key: Char);
  294.  
  295.         procedure ra_seconds_editKeyPress(
  296.                     Sender: TObject;
  297.             var Key: Char);
  298.  
  299.         procedure dec_degrees_editKeyPress(
  300.                     Sender: TObject;
  301.             var Key: Char);
  302.  
  303.         procedure dec_minutes_editKeyPress(
  304.                     Sender: TObject;
  305.             var Key: Char);
  306.  
  307.         procedure dec_seconds_editKeyPress(
  308.                     Sender: TObject;
  309.             var Key: Char);
  310.  
  311.         procedure ra_hours_up_downChanging(
  312.                     Sender: TObject;
  313.             var AllowChange: Boolean);
  314.  
  315.         procedure ra_minutes_up_downChanging(
  316.                     Sender: TObject;
  317.             var AllowChange: Boolean);
  318.  
  319.         procedure ra_seconds_up_downChanging(
  320.                     Sender: TObject;
  321.             var AllowChange: Boolean);
  322.  
  323.         procedure dec_degrees_up_downChanging(
  324.                     Sender: TObject;
  325.             var AllowChange: Boolean);
  326.  
  327.         procedure dec_minutes_up_downChanging(
  328.                     Sender: TObject;
  329.             var AllowChange: Boolean);
  330.  
  331.         procedure dec_seconds_up_downChanging(
  332.                     Sender: TObject;
  333.             var AllowChange: Boolean);
  334.  
  335.         procedure move_degrees_editChange(
  336.             Sender: TObject);
  337.  
  338.         procedure move_minutes_editChange(
  339.             Sender: TObject);
  340.  
  341.         procedure move_seconds_editChange(
  342.             Sender: TObject);
  343.  
  344.     private
  345.         { Private declarations }
  346.         north_south_reversed,
  347.         east_west_reversed:boolean;
  348.     public
  349.         { Public declarations }
  350.         moving_scope:boolean;
  351.         scope_name:shortstring;
  352.         ignore_event_north,
  353.         ignore_event_south,
  354.         ignore_event_west,
  355.         ignore_event_east:longint;
  356.         can_slew,
  357.         can_goto,
  358.         can_sync:boolean;
  359.         { configuration }
  360.         dimensions:dimensions_record;
  361.         { slew controls }
  362.         move_method:integer;
  363.         { window method }
  364.         window_percent:extended;
  365.         { degree method }
  366.         move_degrees,
  367.         move_minutes,
  368.         move_seconds:extended;
  369.         degrees_updating,
  370.         minutes_updating,
  371.         seconds_updating,
  372.         ra_hours_updating,
  373.         ra_minutes_updating,
  374.         ra_seconds_updating,
  375.         dec_degrees_updating,
  376.         dec_minutes_updating,
  377.         dec_seconds_updating:boolean;
  378.  
  379.         procedure normalise(
  380.                     max_degrees:integer;
  381.             var degrees,
  382.                     minutes,
  383.                     seconds:extended);
  384.  
  385.         { events }
  386.         procedure check_visible_and_show_hide(
  387.             sender:tobject);
  388.  
  389.         procedure hide_form;
  390.         procedure show_form;
  391.     end;
  392.  
  393. { global variables }
  394. var
  395.     scope_control:Tscope_control;
  396.  
  397. implementation
  398.  
  399. uses
  400.     ntc_client_network,
  401.     ntc_client_info,
  402.     ntc_client_focus,
  403.     ntc_client_tracking,
  404.     ntc_client_object,
  405.     ntc_client_search;
  406.  
  407. {$R *.dfm}
  408.  
  409.     { -------------
  410.         form controls
  411.         ------------- }
  412.  
  413. procedure tscope_control.formcreate(
  414.     Sender:TObject);
  415. begin
  416.     ignore_event_north:=event_0;
  417.     ignore_event_south:=event_0;
  418.     ignore_event_east:=event_0;
  419.     ignore_event_west:=event_0;
  420.     flip_buttons(false);
  421.     move_degrees_up_down.max:=max_degrees-1;
  422.     move_minutes_up_down.max:=minutes_in_degree-1;
  423.     move_seconds_up_down.max:=seconds_in_minute-1;
  424.     move_degrees_up_down.min:=0;
  425.     move_minutes_up_down.min:=0;
  426.     move_seconds_up_down.min:=0;
  427.     { goto }
  428.     ra_hours_up_down.min:=0;
  429.     ra_minutes_up_down.min:=0;
  430.     ra_seconds_up_down.min:=0;
  431.     dec_degrees_up_down.min:=0;
  432.     dec_minutes_up_down.min:=0;
  433.     dec_seconds_up_down.min:=0;
  434.     ra_hours_up_down.max:=max_hours-1;
  435.     ra_minutes_up_down.max:=minutes_in_degree-1;
  436.     ra_seconds_up_down.max:=seconds_in_minute-1;
  437.     dec_degrees_up_down.max:=max_degrees_dec-1;
  438.     dec_minutes_up_down.max:=minutes_in_degree-1;
  439.     dec_seconds_up_down.max:=seconds_in_minute-1;
  440.     { temporary }
  441.     can_slew:=true;
  442.     window_track.min:=0;
  443.     window_track.max:=window_track_max;
  444.     degrees_updating:=false;
  445.     minutes_updating:=false;
  446.     seconds_updating:=false;
  447.     ra_hours_updating:=false;
  448.     ra_minutes_updating:=false;
  449.     ra_seconds_updating:=false;
  450.     dec_degrees_updating:=false;
  451.     dec_minutes_updating:=false;
  452.     dec_seconds_updating:=false;
  453.     load_settings;
  454.     moving_scope:=false;
  455. end;
  456.  
  457. procedure Tscope_control.form_close_query(
  458.             Sender: TObject;
  459.     var CanClose: Boolean);
  460. begin
  461.     canclose:=false;
  462.     visible:=false;
  463.     with dimensions do
  464.         begin
  465.             form_top:=top;
  466.             form_left:=left;
  467.         end;
  468. end;
  469.  
  470.     { -------------
  471.         scope linkage
  472.         ------------- }
  473.  
  474. procedure Tscope_control.flip_buttons(
  475.     toggle:boolean);
  476. begin
  477.     slew_group.enabled:=toggle;
  478.     if toggle then
  479.         begin
  480.             if move_method=window_method then
  481.                 change_window_method
  482.             else
  483.                 change_degree_method;
  484.         end
  485.     else
  486.         begin
  487.             move_window_group.enabled:=false;
  488.             move_units_group.Enabled:=false;
  489.         end;
  490.     east_button.enabled:=toggle;
  491.     north_button.enabled:=toggle;
  492.     west_button.enabled:=toggle;
  493.     south_button.enabled:=toggle;
  494.     stop_button.enabled:=toggle;
  495.     goto_group.enabled:=toggle;
  496. end;
  497.  
  498. function send_request(
  499.     m,
  500.     e:string)
  501.     :response_type;
  502. begin
  503.     result:=scope_network.send_request(m,e);
  504. end;
  505.  
  506. function send_request_check(
  507.     m:string)
  508.     :response_type;
  509. begin
  510.     result:=scope_network.send_request_check(m);
  511. end;
  512.  
  513. procedure Tscope_control.change_panel(
  514.     toggle:boolean);
  515. begin
  516.     if toggle then
  517.         begin
  518.             if not moving_scope then
  519.                 begin
  520.                     led_display.color:=clRed;
  521.                     led_display.refresh;
  522.                 end;
  523.             if can_slew then
  524.                 flip_buttons(true);
  525.             with scope_focus do
  526.                  if can_focus then
  527.                 begin
  528.                     update_speed_group(
  529.                         speed_box,
  530.                         first_speed_button,
  531.                         start_focus_speed,
  532.                         focus_speeds,
  533.                         speed_button_click,
  534.                         can_focus);
  535.                     flip_buttons(true);
  536.                 end
  537.             else
  538.                 flip_buttons(false);
  539.             with scope_tracking do
  540.                  if can_track then
  541.                 flip_buttons(true);
  542.             scope_search.enable_panel;
  543.             if not moving_scope then
  544.                 begin
  545.                     led_display.color:=clLime;
  546.                     led_display.refresh;
  547.                 end;
  548.             connect_button.Enabled:=not toggle;
  549.             disconnect_button.enabled:=toggle;
  550.         end
  551.     else
  552.         begin
  553.             scope_focus.flip_buttons(false);
  554.             scope_tracking.flip_buttons(false);
  555.             scope_search.disable_panel;
  556.             flip_buttons(false);
  557.             if not moving_scope then
  558.                 begin
  559.                     led_display.color:=clred;
  560.                     led_display.refresh;
  561.                     connect_button.Enabled:=not toggle;
  562.                 end;
  563.             disconnect_button.enabled:=toggle;
  564.         end;
  565.     if scope_focus.focused then
  566.         scope_focus.show;
  567.     if focused then
  568.         Show;
  569. end;
  570.  
  571. procedure Tscope_control.connect_to_scope;
  572. begin
  573.     if send_request('connect','Connection to scope failed')>=[exit_ok] then
  574.         begin
  575.             scope_info.get_info;
  576.             change_panel(true);
  577.         end;
  578. end;
  579.  
  580. procedure tscope_control.disconnect_from_scope;
  581. begin
  582.     if send_request_check('disconnect')>=[exit_ok] then
  583.          with scope_control do
  584.         begin
  585.             led_display.color:=clRed;
  586.             led_display.refresh;
  587.             change_panel(false);
  588.             if focused then
  589.                 show;
  590.         end;
  591. end;
  592.  
  593.     { -------------------
  594.         directional buttons
  595.         ------------------- }
  596.  
  597. procedure tscope_control.stop_failed;
  598. begin
  599.     showmessage(stop_error);
  600. end;
  601.  
  602. procedure tscope_control.move_down;
  603. begin
  604.     scope_search.move_screen('down');
  605. end;
  606.  
  607. procedure tscope_control.move_up;
  608. begin
  609.     scope_search.move_screen('up');
  610. end;
  611.  
  612. procedure tscope_control.move_left;
  613. begin
  614.     scope_search.move_screen('left');
  615. end;
  616.  
  617. procedure tscope_control.move_right;
  618. begin
  619.     scope_search.move_screen('right');
  620. end;
  621.  
  622. procedure tscope_control.move_distance(
  623.     d:string);
  624. var
  625.     t_ra:double;
  626. begin
  627.     t_ra:=move_seconds/seconds_in_minute;
  628.     t_ra:=(t_ra+move_minutes)/minutes_in_degree;
  629.     t_ra:=t_ra+move_degrees;
  630.     scope_network.send_request_check('move_'+d+'(distance='+floattostr(t_ra)+')');
  631.     scope_search.enable_timer;
  632. end;
  633.  
  634. procedure tscope_control.north_button_down(
  635.     Sender:TObject);
  636. begin
  637.     if not moving_scope then
  638.         begin
  639.             moving_scope:=true;
  640.             write_status_log('north - begin');
  641.             if move_method=window_method then
  642.                 begin
  643.                     if north_label.caption='N' then
  644.                         move_up
  645.                     else
  646.                         move_down;
  647.                 end
  648.             else if move_degrees+move_minutes+move_seconds>0 then
  649.                 move_distance('up')
  650.             else
  651.                 moving_scope:=false;
  652.             write_status_log('north - end');
  653.         end;
  654. end;
  655.  
  656. procedure tscope_control.south_button_down(
  657.     Sender:TObject);
  658. begin
  659.     if not moving_scope then
  660.         begin
  661.             moving_scope:=true;
  662.             write_status_log('south - begin');
  663.             if move_method=window_method then
  664.                 begin
  665.                     if north_label.caption='S' then
  666.                         move_up
  667.                     else
  668.                         move_down;
  669.                 end
  670.             else if move_degrees+move_minutes+move_seconds>0 then
  671.                 move_distance('down')
  672.             else
  673.                 moving_scope:=false;
  674.             write_status_log('south - end');
  675.         end;
  676. end;
  677.  
  678. procedure tscope_control.east_button_down(
  679.     Sender:TObject);
  680. begin
  681.     if not moving_scope then
  682.         begin
  683.             moving_scope:=true;
  684.             write_status_log('east - begin');
  685.             if move_method=window_method then
  686.                 begin
  687.                     if north_label.caption='W' then
  688.                         move_left
  689.                     else
  690.                         move_right;
  691.                 end
  692.             else if move_degrees+move_minutes+move_seconds>0 then
  693.                 move_distance('right')
  694.             else
  695.                 moving_scope:=false;
  696.             write_status_log('east - end');
  697.         end;
  698. end;
  699.  
  700. procedure tscope_control.west_button_down(
  701.     Sender:TObject);
  702. begin
  703.     if not moving_scope then
  704.         begin
  705.             moving_scope:=true;
  706.             write_status_log('west - begin');
  707.             if move_method=window_method then
  708.                 begin
  709.                     if north_label.caption='E' then
  710.                         move_left
  711.                     else
  712.                         move_right;
  713.                 end
  714.             else if move_degrees+move_minutes+move_seconds>0 then
  715.                 move_distance('left')
  716.             else
  717.                 moving_scope:=false;
  718.             write_status_log('west - end');
  719.         end;
  720. end;
  721.  
  722. procedure tscope_control.stop_scope;
  723. begin
  724.     if not (send_request_check('stop')>=[exit_ok]) then
  725.         stop_failed;
  726. end;
  727.  
  728. procedure tscope_control.stop_button_down(
  729.     Sender:TObject);
  730. begin
  731.     stop_scope;
  732. end;
  733.  
  734.     { ----
  735.         goto
  736.         ---- }
  737.  
  738. procedure tscope_control.go_to;
  739. begin
  740.     with current_object do
  741.         begin
  742.             ra:=strtointdef(ra_seconds_edit.text,0)/60;
  743.             ra:=(ra+strtointdef(ra_minutes_edit.text,0)/60);
  744.             ra:=ra+strtointdef(ra_hours_edit.text,0);
  745.             dec:=strtointdef(dec_seconds_edit.text,0)/60;
  746.             dec:=(dec+strtointdef(dec_minutes_edit.text,0)/60);
  747.             dec:=dec+strtointdef(dec_degrees_edit.text,0);
  748.             send_request_check('goto(ra='+floattostr(ra)+',dec='+floattostr(dec)+')');
  749.         end;
  750. end;
  751.  
  752.     { --------------
  753.         speed controls
  754.         -------------- }
  755.  
  756. procedure tscope_control.update_speed_group(
  757.     speed_box:tpanel;
  758.     first_speed_button:tspeedbutton;
  759.     start_speed,
  760.     speed_count:integer;
  761.     event:TNotifyEvent;
  762.     can_do:boolean);
  763. var
  764.     c,i,j,k,bh,bw,bl,bt:integer;
  765.     n,l,r,t:tspeedbutton;
  766.     x,y:extended;
  767. begin
  768.     if can_do then
  769.          with speed_box do
  770.         begin
  771.             r:=first_speed_button;
  772.             n:=tspeedbutton(r.tag);
  773.             i:=speed_count;
  774.             while n<>nil do
  775.                 begin
  776.                     l:=n;
  777.                     n:=tspeedbutton(n.tag);
  778.                     dec(i);
  779.                     if i<=0 then
  780.                         begin
  781.                             if i=0 then
  782.                                 begin
  783.                                     t:=tspeedbutton(r.tag);
  784.                                     r.Tag:=longint(nil);
  785.                                     r:=t;
  786.                                 end
  787.                             else
  788.                                 r:=tspeedbutton(r.tag);
  789.                             l.free;
  790.                         end
  791.                     else
  792.                         r:=tspeedbutton(r.tag);
  793.                 end;
  794.             while i>1 do
  795.                 begin
  796.                     r.tag:=longint(tspeedbutton.create(self));
  797.                     r:=tspeedbutton(r.tag);
  798.                     r.tag:=longint(nil);
  799.                     r.Parent:=speed_box;
  800.                     dec(i);
  801.                 end;
  802.             x:=speed_count;
  803.             i:=trunc(sqrt(x));
  804.             if i>1 then
  805.                 begin
  806.                     y:=sqr(i+1);
  807.                     j:=trunc(sqrt(y));
  808.                     k:=speed_count div j;
  809.                     if (k>=i) and (speed_count mod j<>0) then
  810.                         begin
  811.                             k:=-1;
  812.                             inc(i);
  813.                         end;
  814.                 end
  815.             else
  816.                 k:=0;
  817.             if height>=width then
  818.                 begin
  819.                     if i<=1 then
  820.                         begin
  821.                             if speed_count>1 then
  822.                                 bh:=height div speed_count
  823.                             else
  824.                                 begin
  825.                                     bh:=height;
  826.                                     i:=1
  827.                                 end;
  828.                         end
  829.                     else if (k>=0) and ((speed_count mod i<>0) or (k>=i)) then
  830.                         bh:=height div (i+1)
  831.                     else
  832.                         bh:=height div i;
  833.                     n:=first_speed_button;
  834.                     if i>1 then
  835.                         bw:=width div i
  836.                     else
  837.                         begin
  838.                             bw:=width;
  839.                             n.Caption:=inttostr(start_speed);
  840.                         end;
  841.                 end
  842.             else
  843.                 begin
  844.                     if i<=1 then
  845.                         begin
  846.                             if speed_count>1 then
  847.                                 bw:=width div speed_count
  848.                             else
  849.                                 begin
  850.                                     bw:=width;
  851.                                     i:=1
  852.                                 end;
  853.                         end
  854.                     else if (k>=0) and ((speed_count mod i<>0) or (k>=i)) then
  855.                         bw:=width div (i+1)
  856.                     else
  857.                         bw:=width div i;
  858.                     n:=first_speed_button;
  859.                     if i>1 then
  860.                         bh:=height div i
  861.                     else
  862.                         begin
  863.                             bh:=height;
  864.                             n.Caption:=inttostr(start_speed);
  865.                         end;
  866.                 end;
  867.             bl:=0;
  868.             bt:=0;
  869.             c:=start_speed;
  870.             while n<>nil do
  871.                  with n do
  872.                 begin
  873.                     Width:=bw;
  874.                     top:=bt;
  875.                     left:=bl;
  876.                     inc(bl,bw);
  877.                     with speed_box do
  878.                          if height>=width then
  879.                         begin
  880.                             if bl+(bw div 2)>width then
  881.                                 begin
  882.                                     bl:=0;
  883.                                     inc(bt,bh);
  884.                                 end;
  885.                         end
  886.                     else if bt+(bh div 2)>Height then
  887.                         begin
  888.                             bt:=0;
  889.                             inc(bl,bw);
  890.                         end;
  891.                     Height:=bh;
  892.                     down:=false;
  893.                     groupindex:=1;
  894.                     allowallup:=false;
  895.                     caption:=inttostr(c);
  896.                     visible:=true;
  897.                     enabled:=true;
  898.                     onclick:=event;
  899.                     inc(c);
  900.                     n:=tspeedbutton(Tag);
  901.                 end;
  902.             first_speed_button.down:=true;
  903.         end;
  904. end;
  905.  
  906. function tscope_control.set_slew_speed(
  907.     speed_box:tpanel)
  908.     :integer;
  909. var
  910.     i:integer;
  911. begin
  912.     result:=1;
  913.     for I:= 0 to speed_box.ControlCount -1 do
  914.         begin
  915.             if tspeedbutton(speed_box.controls[i]).down=true then
  916.                 begin
  917.                     result:=strtointdef(tspeedbutton(speed_box.controls[i]).caption,i+1);
  918.                     exit;
  919.                 end;
  920.         end;
  921. end;
  922.  
  923.     { -------
  924.         logging
  925.         ------- }
  926.  
  927. procedure tscope_control.write_status_log(
  928.     e:string);
  929. begin
  930.     scope_network.write_status_log_check(e);
  931. end;
  932.  
  933.     { -------------
  934.         configuration
  935.         ------------- }
  936.  
  937. procedure tscope_control.load_settings;
  938. begin
  939.     ini_file:=tinifile.create(application_path+'client.ini');
  940.     with ini_file do
  941.         begin
  942.             move_method:=readinteger('control','move_method',window_method);
  943.             window_percent:=
  944.                 readfloat('control','window_percent',window_percent_default);
  945.             move_degrees:=readfloat('control','move_degrees',move_degrees_default);
  946.             move_minutes:=readfloat('control','move_minutes',move_minutes_default);
  947.             move_seconds:=readfloat('control','move_seconds',move_seconds_default);
  948.             window_track.Position:=trunc(window_percent) div window_track_step;
  949.             degrees_edit.text:=floattostr(window_percent);
  950.             update_degrees;
  951.             move_degrees_up_down.position:=trunc(move_degrees);
  952.             move_minutes_up_down.position:=trunc(move_minutes);
  953.             move_seconds_up_down.position:=trunc(move_seconds);
  954.             if move_method=window_method then
  955.                 window_move_button.down:=true
  956.             else
  957.                 degree_move_button.down:=true;
  958.             north_south_reversed:=ReadBool('control','swap_north_south',false);
  959.             east_west_reversed:=ReadBool('control','swap_east_west',false);
  960.             can_goto:=ReadBool('control','can_goto',false);
  961.             can_sync:=ReadBool('control','can_sync',false);
  962.             if north_south_reversed then
  963.                 begin
  964.                     north_label.Caption:='S';
  965.                     south_label.caption:='N';
  966.                 end
  967.             else
  968.                 begin
  969.                     north_label.Caption:='N';
  970.                     south_label.caption:='S';
  971.                 end;
  972.             if east_west_reversed then
  973.                 begin
  974.                     east_label.Caption:='W';
  975.                     west_label.caption:='E';
  976.                 end
  977.             else
  978.                 begin
  979.                     east_label.Caption:='E';
  980.                     west_label.caption:='W';
  981.                 end;
  982.             locked_check.checked:=true;
  983.             { form }
  984.             scope.get_dimensions(scope_control,@dimensions,'control',ini_file);
  985.             left:=dimensions.form_left;
  986.             top:=dimensions.form_top;
  987.             visible:=readbool('control','visible',false);
  988.         end;
  989.     ini_file.free;
  990. end;
  991.  
  992. procedure tscope_control.save_settings;
  993. begin
  994.     with ini_file do
  995.         begin
  996.             writeinteger('control','move_method',move_method);
  997.             writefloat('control','window_percent',window_percent);
  998.             writefloat('control','move_degrees',move_degrees);
  999.             writefloat('control','move_minutes',move_minutes);
  1000.             writefloat('control','move_seconds',move_seconds);
  1001.             writeBool('control','swap_north_south',north_south_reversed);
  1002.             writeBool('control','swap_east_west',east_west_reversed);
  1003.             writeBool('control','can_goto',can_goto);
  1004.             writeBool('control','can_sync',can_sync);
  1005.             { form }
  1006.             scope.find_vdu(scope_control,@dimensions);
  1007.             scope.write_dimensions(@dimensions,left,top,'control',ini_file);
  1008.             writebool('control','visible',visible);
  1009.         end;
  1010. end;
  1011.  
  1012.     { --------
  1013.         utilites
  1014.         -------- }
  1015.  
  1016. procedure Tscope_control.change_window_method;
  1017. begin
  1018.     move_units_group.enabled:=false;
  1019.     move_degrees_edit.enabled:=false;
  1020.     move_minutes_edit.enabled:=false;
  1021.     move_seconds_edit.enabled:=false;
  1022.     move_degrees_up_down.Enabled:=false;
  1023.     move_minutes_up_down.Enabled:=false;
  1024.     move_seconds_up_down.Enabled:=false;
  1025.     move_degrees_label.Enabled:=false;
  1026.     move_minutes_label.Enabled:=false;
  1027.     move_seconds_label.Enabled:=false;
  1028.     window_track.Enabled:=true;
  1029.     degrees_edit.enabled:=true;
  1030.     move_window_group.enabled:=true;
  1031.     move_method:=window_method;
  1032.     window_move_button.down:=true;
  1033. end;
  1034.  
  1035. procedure Tscope_control.change_degree_method;
  1036. begin
  1037.     move_window_group.enabled:=false;
  1038.     window_track.Enabled:=false;
  1039.     degrees_edit.enabled:=false;
  1040.     move_degrees_edit.enabled:=true;
  1041.     move_minutes_edit.enabled:=true;
  1042.     move_seconds_edit.enabled:=true;
  1043.     move_degrees_up_down.Enabled:=true;
  1044.     move_minutes_up_down.Enabled:=true;
  1045.     move_seconds_up_down.Enabled:=true;
  1046.     move_degrees_label.Enabled:=true;
  1047.     move_minutes_label.Enabled:=true;
  1048.     move_seconds_label.Enabled:=true;
  1049.     move_units_group.enabled:=true;
  1050.     move_method:=degree_method;
  1051.     degree_move_button.down:=true;
  1052. end;
  1053.  
  1054. procedure Tscope_control.normalise(
  1055.             max_degrees:integer;
  1056.     var degrees,
  1057.             minutes,
  1058.             seconds:extended);
  1059. begin
  1060.     if (degrees>0) and (degrees>=max_degrees) then
  1061.         degrees:=max_degrees-1
  1062.     else if (degrees<0) and (degrees<=-max_degrees) then
  1063.         degrees:=-(max_degrees-1);
  1064.     if frac(degrees)<>0 then
  1065.         begin
  1066.             minutes:=0;
  1067.             seconds:=0;
  1068.             minutes:=frac(degrees)*minutes_in_degree;
  1069.             degrees:=trunc(degrees);
  1070.             seconds:=frac(minutes)*seconds_in_minute;
  1071.             minutes:=trunc(minutes);
  1072.         end
  1073.     else if frac(minutes)<>0 then
  1074.         begin
  1075.             seconds:=0;
  1076.             seconds:=frac(minutes)*seconds_in_minute;
  1077.             minutes:=trunc(minutes);
  1078.         end;
  1079. end;
  1080.  
  1081. procedure Tscope_control.update_degrees;
  1082. begin
  1083.     normalise(max_degrees,move_degrees,move_minutes,move_seconds);
  1084. end;
  1085.  
  1086. procedure Tscope_control.update_edit_boxes;
  1087. begin
  1088.     move_degrees:=strtofloatdef(move_degrees_edit.text,move_degrees);
  1089.     move_minutes:=strtofloatdef(move_minutes_edit.text,move_minutes);
  1090.     move_seconds:=strtofloatdef(move_seconds_edit.text,move_seconds);
  1091.     update_degrees;
  1092.     move_degrees_edit.text:=floattostr(move_degrees);
  1093.     move_minutes_edit.Text:=floattostr(move_minutes);
  1094.     move_seconds_edit.text:=floattostr(move_seconds);
  1095.     move_degrees_up_down.position:=trunc(move_degrees);
  1096.     move_minutes_up_down.position:=trunc(move_minutes);
  1097.     move_seconds_up_down.position:=trunc(move_seconds);
  1098. end;
  1099.  
  1100.     { ------
  1101.         events
  1102.         ------ }
  1103.  
  1104. procedure Tscope_control.FormShow(
  1105.     Sender:TObject);
  1106. begin
  1107.     with dimensions do
  1108.         begin
  1109.             top:=form_top;
  1110.             left:=form_left;
  1111.         end;
  1112. end;
  1113.  
  1114. procedure tscope_control.adjust;
  1115. begin
  1116.     with dimensions do
  1117.         begin
  1118.             form_top:=trunc(form_top/last_screen_height*current_height);
  1119.             form_left:=trunc(form_left/last_screen_width*current_width);
  1120.         end;
  1121.     if visible then
  1122.         show;
  1123. end;
  1124.  
  1125. procedure tscope_control.check_visible_and_show_hide(
  1126.     sender:tobject);
  1127. begin
  1128.     if visible then
  1129.         hide_form
  1130.     else
  1131.         show_form;
  1132.     scope.show_hide(sender,visible);
  1133. end;
  1134.  
  1135. procedure tscope_control.hide_form;
  1136. begin
  1137.     with dimensions do
  1138.         begin
  1139.             form_top:=top;
  1140.             form_left:=left;
  1141.         end;
  1142.     Visible:=false;
  1143. end;
  1144.  
  1145. procedure tscope_control.show_form;
  1146. begin
  1147.     Visible:=true;
  1148. end;
  1149.  
  1150. procedure Tscope_control.check_activate(
  1151.     Sender: TObject);
  1152. begin
  1153.     scope.form_activate(scope_control,@dimensions);
  1154. end;
  1155.  
  1156. procedure Tscope_control.east_labelClick(
  1157.     Sender: TObject);
  1158. begin
  1159.     if not locked_check.checked then
  1160.         begin
  1161.             east_west_reversed:=east_label.caption='E';
  1162.             if east_west_reversed then
  1163.                 begin
  1164.                     east_label.caption:='W';
  1165.                     west_label.caption:='E';
  1166.                 end
  1167.             else
  1168.                 begin
  1169.                     east_label.caption:='E';
  1170.                     west_label.caption:='W';
  1171.                 end;
  1172.         end;
  1173. end;
  1174.  
  1175. procedure Tscope_control.west_labelClick(
  1176.     Sender: TObject);
  1177. begin
  1178.     if not locked_check.checked then
  1179.         begin
  1180.             east_west_reversed:=west_label.caption='W';
  1181.             if east_west_reversed then
  1182.                 begin
  1183.                     east_label.caption:='W';
  1184.                     west_label.caption:='E';
  1185.                 end
  1186.             else
  1187.                 begin
  1188.                     east_label.caption:='E';
  1189.                     west_label.caption:='W';
  1190.                 end;
  1191.         end;
  1192. end;
  1193.  
  1194. procedure Tscope_control.north_labelClick(
  1195.     Sender: TObject);
  1196. begin
  1197.     if not locked_check.checked then
  1198.         begin
  1199.             north_south_reversed:=north_label.caption='N';
  1200.             if north_south_reversed then
  1201.                 begin
  1202.                     north_label.caption:='S';
  1203.                     south_label.caption:='N';
  1204.                 end
  1205.             else
  1206.                 begin
  1207.                     north_label.caption:='N';
  1208.                     south_label.caption:='S';
  1209.                 end;
  1210.         end;
  1211. end;
  1212.  
  1213. procedure Tscope_control.south_labelClick(
  1214.     Sender: TObject);
  1215. begin
  1216.     if not locked_check.checked then
  1217.         begin
  1218.             north_south_reversed:=south_label.caption='S';
  1219.             if north_south_reversed then
  1220.                 begin
  1221.                     north_label.caption:='S';
  1222.                     south_label.caption:='N';
  1223.                 end
  1224.             else
  1225.                 begin
  1226.                     north_label.caption:='N';
  1227.                     south_label.caption:='S';
  1228.                 end;
  1229.         end;
  1230. end;
  1231.  
  1232. procedure tscope_control.connect_to_scope_click(
  1233.     sender:tobject);
  1234. begin
  1235.     if scope_network.scope_client.connected and not moving_scope then
  1236.         connect_to_scope;
  1237. end;
  1238.  
  1239. procedure Tscope_control.disconnect_from_scope_click(
  1240.     Sender:TObject);
  1241. begin
  1242.     if scope_network.scope_client.connected and not moving_scope then
  1243.         disconnect_from_scope;
  1244. end;
  1245.  
  1246. procedure Tscope_control.goto_buttonClick(
  1247.     Sender: TObject);
  1248. begin
  1249.     go_to;
  1250. end;
  1251.  
  1252. procedure Tscope_control.degrees_editKeyPress(
  1253.             Sender: TObject;
  1254.     var Key: Char);
  1255. var
  1256.     t:extended;
  1257. begin
  1258.     if key=cr then
  1259.         begin
  1260.             t:=strtofloatdef(degrees_edit.text,0.5);
  1261.             if (t<=100) and (t>=0) then
  1262.                 begin
  1263.                     move_degrees:=t;
  1264.                     window_track.position:=trunc(t) div window_track_step;
  1265.                 end;
  1266.         end;
  1267. end;
  1268.  
  1269. procedure Tscope_control.window_trackChange(
  1270.     Sender: TObject);
  1271. begin
  1272.     with window_track do
  1273.         begin
  1274.             window_percent:=position*window_track_step;
  1275.             degrees_edit.text:=floattostr(window_percent);
  1276.         end;
  1277. end;
  1278.  
  1279. procedure Tscope_control.window_move_buttonClick(
  1280.     Sender: TObject);
  1281. begin
  1282.     change_window_method;
  1283. end;
  1284.  
  1285. procedure Tscope_control.degree_move_buttonClick(
  1286.     Sender: TObject);
  1287. begin
  1288.     change_degree_method;
  1289. end;
  1290.  
  1291. procedure Tscope_control.move_degrees_editKeyPress(
  1292.             Sender: TObject;
  1293.     var Key: Char);
  1294. begin
  1295.     if key=cr then
  1296.         update_edit_boxes;
  1297. end;
  1298.  
  1299. procedure Tscope_control.move_minutes_editKeyPress(
  1300.             Sender: TObject;
  1301.     var Key: Char);
  1302. begin
  1303.     if key=cr then
  1304.         update_edit_boxes;
  1305. end;
  1306.  
  1307. procedure Tscope_control.move_seconds_editKeyPress(
  1308.             Sender: TObject;
  1309.     var Key: Char);
  1310. begin
  1311.     if key=cr then
  1312.         update_edit_boxes;
  1313. end;
  1314.  
  1315. procedure Tscope_control.move_degrees_up_downChanging(
  1316.             Sender: TObject;
  1317.     var AllowChange: Boolean);
  1318. begin
  1319.     if not degrees_updating then
  1320.         begin
  1321.             degrees_updating:=true;
  1322.             update_edit_boxes;
  1323.             degrees_updating:=false;
  1324.         end;
  1325. end;
  1326.  
  1327. procedure Tscope_control.move_minutes_up_downChanging(
  1328.             Sender: TObject;
  1329.     var AllowChange: Boolean);
  1330. begin
  1331.     if not minutes_updating then
  1332.         begin
  1333.             minutes_updating:=true;
  1334.             update_edit_boxes;
  1335.             minutes_updating:=false;
  1336.         end;
  1337. end;
  1338.  
  1339. procedure Tscope_control.move_seconds_up_downChanging(
  1340.             Sender: TObject;
  1341.     var AllowChange: Boolean);
  1342. begin
  1343.     if not seconds_updating then
  1344.         begin
  1345.             seconds_updating:=true;
  1346.             update_edit_boxes;
  1347.             seconds_updating:=false;
  1348.         end;
  1349. end;
  1350.  
  1351. procedure Tscope_control.move_degrees_editEnter(
  1352.     Sender: TObject);
  1353. begin
  1354.     update_edit_boxes;
  1355. end;
  1356.  
  1357. procedure Tscope_control.update_ra_edit_boxes;
  1358. var
  1359.     ra_h,ra_m,ra_s:extended;
  1360. begin
  1361.     ra_h:=strtofloatdef(ra_hours_edit.text,0);
  1362.     ra_m:=strtofloatdef(ra_minutes_edit.text,0);
  1363.     ra_s:=strtofloatdef(ra_seconds_edit.text,0);
  1364.     normalise(max_hours,ra_h,ra_m,ra_s);
  1365.     ra_hours_edit.text:=floattostr(ra_h);
  1366.     ra_minutes_edit.Text:=floattostr(ra_m);
  1367.     ra_seconds_edit.text:=floattostr(ra_s);
  1368.     ra_hours_up_down.position:=trunc(ra_h);
  1369.     ra_minutes_up_down.position:=trunc(ra_m);
  1370.     ra_seconds_up_down.position:=trunc(ra_s);
  1371. end;
  1372.  
  1373. procedure Tscope_control.ra_hours_editKeyPress(
  1374.             Sender: TObject;
  1375.     var Key: Char);
  1376. begin
  1377.     if key=cr then
  1378.         update_ra_edit_boxes;
  1379. end;
  1380.  
  1381. procedure Tscope_control.ra_minutes_editKeyPress(
  1382.             Sender: TObject;
  1383.     var Key: Char);
  1384. begin
  1385.     if key=cr then
  1386.         update_ra_edit_boxes;
  1387. end;
  1388.  
  1389. procedure Tscope_control.ra_seconds_editKeyPress(
  1390.             Sender: TObject;
  1391.     var Key: Char);
  1392. begin
  1393.     if key=cr then
  1394.         update_ra_edit_boxes;
  1395. end;
  1396.  
  1397. procedure Tscope_control.update_dec_edit_boxes;
  1398. var
  1399.     dec_d,dec_m,dec_s:extended;
  1400. begin
  1401.     dec_d:=strtofloatdef(dec_degrees_edit.text,0);
  1402.     dec_m:=strtofloatdef(dec_minutes_edit.text,0);
  1403.     dec_s:=strtofloatdef(dec_seconds_edit.text,0);
  1404.     normalise(max_degrees_dec,dec_d,dec_m,dec_s);
  1405.     dec_degrees_edit.text:=floattostr(dec_d);
  1406.     dec_minutes_edit.Text:=floattostr(dec_m);
  1407.     dec_seconds_edit.text:=floattostr(dec_s);
  1408.     dec_degrees_up_down.position:=trunc(dec_d);
  1409.     dec_minutes_up_down.position:=trunc(dec_m);
  1410.     dec_seconds_up_down.position:=trunc(dec_s);
  1411. end;
  1412.  
  1413. procedure Tscope_control.dec_degrees_editKeyPress(
  1414.             Sender: TObject;
  1415.     var Key: Char);
  1416. begin
  1417.     if key=cr then
  1418.         update_dec_edit_boxes;
  1419. end;
  1420.  
  1421. procedure Tscope_control.dec_minutes_editKeyPress(
  1422.             Sender: TObject;
  1423.     var Key: Char);
  1424. begin
  1425.     if key=cr then
  1426.         update_dec_edit_boxes;
  1427. end;
  1428.  
  1429. procedure Tscope_control.dec_seconds_editKeyPress(
  1430.             Sender: TObject;
  1431.     var Key: Char);
  1432. begin
  1433.     if key=cr then
  1434.         update_dec_edit_boxes;
  1435. end;
  1436.  
  1437. procedure Tscope_control.ra_hours_up_downChanging(
  1438.             Sender: TObject;
  1439.     var AllowChange: Boolean);
  1440. begin
  1441.     if not ra_hours_updating then
  1442.         begin
  1443.             ra_hours_updating:=true;
  1444.             update_ra_edit_boxes;
  1445.             ra_hours_updating:=false;
  1446.         end;
  1447. end;
  1448.  
  1449. procedure Tscope_control.ra_minutes_up_downChanging(
  1450.             Sender: TObject;
  1451.     var AllowChange: Boolean);
  1452. begin
  1453.     if not ra_minutes_updating then
  1454.         begin
  1455.             ra_minutes_updating:=true;
  1456.             update_ra_edit_boxes;
  1457.             ra_minutes_updating:=false;
  1458.         end;
  1459. end;
  1460.  
  1461. procedure Tscope_control.ra_seconds_up_downChanging(
  1462.             Sender: TObject;
  1463.     var AllowChange: Boolean);
  1464. begin
  1465.     if not ra_seconds_updating then
  1466.         begin
  1467.             ra_seconds_updating:=true;
  1468.             update_ra_edit_boxes;
  1469.             ra_seconds_updating:=false;
  1470.         end;
  1471. end;
  1472.  
  1473. procedure Tscope_control.dec_degrees_up_downChanging(
  1474.             Sender: TObject;
  1475.     var AllowChange: Boolean);
  1476. begin
  1477.     if not dec_degrees_updating then
  1478.         begin
  1479.             dec_degrees_updating:=true;
  1480.             update_dec_edit_boxes;
  1481.             dec_degrees_updating:=false;
  1482.         end;
  1483. end;
  1484.  
  1485. procedure Tscope_control.dec_minutes_up_downChanging(
  1486.             Sender: TObject;
  1487.     var AllowChange: Boolean);
  1488. begin
  1489.     if not dec_minutes_updating then
  1490.         begin
  1491.             dec_minutes_updating:=true;
  1492.             update_dec_edit_boxes;
  1493.             dec_minutes_updating:=false;
  1494.         end;
  1495. end;
  1496.  
  1497. procedure Tscope_control.dec_seconds_up_downChanging(
  1498.             Sender: TObject;
  1499.     var AllowChange: Boolean);
  1500. begin
  1501.     if not dec_seconds_updating then
  1502.         begin
  1503.             dec_seconds_updating:=true;
  1504.             update_dec_edit_boxes;
  1505.             dec_seconds_updating:=false;
  1506.         end;
  1507. end;
  1508.  
  1509. procedure Tscope_control.move_degrees_editChange(
  1510.     Sender: TObject);
  1511. begin
  1512.     update_edit_boxes;
  1513. end;
  1514.  
  1515. procedure Tscope_control.move_minutes_editChange(
  1516.     Sender: TObject);
  1517. begin
  1518.     update_edit_boxes;
  1519. end;
  1520.  
  1521. procedure Tscope_control.move_seconds_editChange(
  1522.     Sender: TObject);
  1523. begin
  1524.     update_edit_boxes;
  1525. end;
  1526.  
  1527. end.
  1528.  
  1529.